package cn.fufeiii.bt.demo.springretry;

import cn.fufeiii.bt.demo.mybatisplus.StudentMpDO;
import cn.fufeiii.bt.demo.mybatisplus.StudentMpDao;
import cn.fufeiii.bt.demo.springjpa.StudentJpaDO;
import cn.fufeiii.bt.demo.springjpa.StudentJpaDORepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author FuFei
 */
@Slf4j
@Service
public class RetryService {
    @Autowired
    private StudentMpDao studentMpDao;
    @Autowired
    private StudentJpaDORepository studentJpaDORepository;

    @Retryable(include = Exception.class, backoff = @Backoff)
    public String simple(Integer param) {
        log.info("simple...");
        if (param == 0) {
            throw new RuntimeException("业务异常");
        }
        return "ok";
    }


    @Retryable(include = Exception.class, backoff = @Backoff(delay = 100))
    @Transactional(rollbackFor = Exception.class)
    public String mp(Integer param) {
        log.info("MP...");
        studentMpDao.insert(StudentMpDO.builder().sno("1").name(System.currentTimeMillis() + "").build());
        if (param > 0) {
            throw new RuntimeException("业务异常");
        }
        // 最终不会保存数据
        return "ok";
    }


    @Recover
    @Transactional(rollbackFor = Exception.class)
    public String retryFb(Exception e, Integer param) {
        // 注意这里的recover不会走aop，所以其事务也不会生效
        // 除非之类调用其他service从新走aop的逻辑
        log.info("mpFb...");
        studentMpDao.insert(StudentMpDO.builder().sno("2").name(System.currentTimeMillis() + "").build());
        if (param == 1) {
            throw new RuntimeException("mpFb");
        }
        studentMpDao.insert(StudentMpDO.builder().sno("21").name(System.currentTimeMillis() + "").build());
        return "okk";
    }


    //    @Retryable(include = Exception.class, backoff = @Backoff(delay = 100))
    @Transactional(rollbackFor = Exception.class)
    public String jpa(Integer param) {
        log.info("JPA...");
        studentJpaDORepository.save(StudentJpaDO.builder().sno("1").name(System.currentTimeMillis() + "").build());
        if (param > 0) {
            throw new RuntimeException("业务异常");
        }
        // 最终不会保存数据
        return "ok";
    }

}
